/**
* Copyright [2009] [NIC Labs]
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or
* agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
**/
package cl.nic.dte.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.AlgorithmParameters;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.security.interfaces.DSAPrivateKey;
import java.security.interfaces.DSAPublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.crypto.Cipher;
import javax.crypto.EncryptedPrivateKeyInfo;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamSource;
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
import org.apache.fop.apps.MimeConstants;
public class Utilities {
public static DateFormat fechaFormat = null;
public static DateFormat fechaEstadoDte = null;
public static DateFormat fechaMesFormat = null;
public static DateFormat fechaHoraFormat = null;
public static ResourceBundle verificationLabels = null;
public static ResourceBundle netLabels = null;
public static ResourceBundle exceptions = null;
static {
String prop1 = System.getProperty("sii.dte.ConfigurationFile");
ResourceBundle conf1 = null;
if (prop1 != null)
conf1 = ResourceBundle.getBundle(prop1);
ResourceBundle conf2 = ResourceBundle
.getBundle("cl.nic.dte.resources.Configuration");
Locale language;
if (conf1 != null && conf1.getString("LOCALE") != null)
language = new Locale(conf1.getString("LOCALE"));
else
language = new Locale(conf2.getString("LOCALE"));
verificationLabels = ResourceBundle.getBundle(
"cl.nic.dte.resources.VerifyResults", language);
netLabels = ResourceBundle.getBundle("cl.nic.dte.resources.Net",
language);
exceptions = ResourceBundle.getBundle(
"cl.nic.dte.resources.Exceptions", language);
if (conf1 != null && conf1.getString("FECHA_TYPE_FORMAT") != null)
fechaFormat = new SimpleDateFormat(conf1
.getString("FECHA_TYPE_FORMAT"));
else
fechaFormat = new SimpleDateFormat(conf2
.getString("FECHA_TYPE_FORMAT"));
if (conf1 != null && conf1.getString("FECHA_MES_TYPE_FORMAT") != null)
fechaMesFormat = new SimpleDateFormat(conf1
.getString("FECHA_MES_TYPE_FORMAT"));
else
fechaMesFormat = new SimpleDateFormat(conf2
.getString("FECHA_MES_TYPE_FORMAT"));
if (conf1 != null && conf1.getString("FECHA_HORA_TYPE_FORMAT") != null)
fechaHoraFormat = new SimpleDateFormat(conf1
.getString("FECHA_HORA_TYPE_FORMAT"));
else
fechaHoraFormat = new SimpleDateFormat(conf2
.getString("FECHA_HORA_TYPE_FORMAT"));
if (conf1 != null && conf1.getString("FECHA_ESTADO_DTE") != null)
fechaEstadoDte = new SimpleDateFormat(conf1
.getString("FECHA_ESTADO_DTE"));
else
fechaEstadoDte = new SimpleDateFormat(conf2
.getString("FECHA_ESTADO_DTE"));
}
public static PrivateKey readPrivateKeyFromFile(String fileName,
String algo, char[] password) throws IOException,
NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeySpecException, InvalidKeyException,
InvalidAlgorithmParameterException {
return Utilities.readPrivateKey(
new FileInputStream(new File(fileName)), algo, password);
}
public static PrivateKey readPrivateKey(InputStream in, String algo,
char[] password) throws IOException, NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeySpecException,
InvalidKeyException, InvalidAlgorithmParameterException {
byte[] datos = new byte[in.available()];
while (in.available() > 0)
in.read(datos);
return Utilities.readPrivateKey(datos, algo, password);
}
public static PrivateKey readPrivateKey(byte[] datos, String algo,
char[] password) throws IOException, NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeySpecException,
InvalidKeyException, InvalidAlgorithmParameterException {
PKCS8EncodedKeySpec pkcs8KeySpec = null;
if (password != null) {
EncryptedPrivateKeyInfo ekey = new EncryptedPrivateKeyInfo(datos);
Cipher cip = Cipher.getInstance(ekey.getAlgName());
PBEKeySpec pspec = new PBEKeySpec(password);
SecretKeyFactory skfac = SecretKeyFactory.getInstance(ekey
.getAlgName());
Key pbeKey = skfac.generateSecret(pspec);
AlgorithmParameters algParams = ekey.getAlgParameters();
cip.init(Cipher.DECRYPT_MODE, pbeKey, algParams);
pkcs8KeySpec = ekey.getKeySpec(cip);
} else {
pkcs8KeySpec = new PKCS8EncodedKeySpec(datos);
}
KeyFactory rsaKeyFac = KeyFactory.getInstance(algo);
return (PrivateKey) rsaKeyFac.generatePrivate(pkcs8KeySpec);
}
public static boolean correspond(PublicKey pubKey, PrivateKey prvKey)
throws NoSuchAlgorithmException {
ResourceBundle labels = ResourceBundle
.getBundle("cl.nic.dte.resources.Exceptions");
if (!pubKey.getAlgorithm().equals(prvKey.getAlgorithm()))
return false;
if (pubKey.getAlgorithm().equals("RSA")) {
if (!((RSAPrivateKey) prvKey).getModulus().equals(
((RSAPublicKey) pubKey).getModulus()))
return false;
return true;
} else if (pubKey.getAlgorithm().equals("DSA")) {
if (!(((DSAPrivateKey) prvKey).getParams().getG()
.equals(((DSAPublicKey) pubKey).getParams().getG())))
return false;
if (!(((DSAPrivateKey) prvKey).getParams().getP()
.equals(((DSAPublicKey) pubKey).getParams().getP())))
return false;
if (!(((DSAPrivateKey) prvKey).getParams().getQ()
.equals(((DSAPublicKey) pubKey).getParams().getQ())))
return false;
return true;
} else
throw new NoSuchAlgorithmException(labels
.getString("ALG_NOT_SUPPORTED"));
}
public static Date getDate(String date) throws ParseException {
return fechaFormat.parse(date);
}
public static void generatePDF(InputStream xmlFile, InputStream xslFile,
OutputStream pdfFile) throws FOPException, FileNotFoundException,
TransformerException {
FopFactory fopFactory = FopFactory.newInstance();
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
// configure foUserAgent as desired
// Construct fop with desired output format
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent,
pdfFile);
// Setup XSLT
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(new StreamSource(
xslFile));
// Set the value of a <param> in the stylesheet
transformer.setParameter("versionParam", "2.0");
// Setup input for XSLT transformation
Source src = new StreamSource(xmlFile);
// Resulting SAX events (the generated FO) must be piped through to FOP
Result res = new SAXResult(fop.getDefaultHandler());
// res = new StreamResult(new File("data/generated/sample-fo.xml"));
// Start XSLT transformation and FOP processing
transformer.transform(src, res);
}
public static String getRutFormatted(String rut) {
rut = rut.substring(0, rut.length() - 8) + "."
+ rut.substring(rut.length() - 8, rut.length() - 5) + "."
+ rut.substring(rut.length() - 5, rut.length());
return rut;
}
/**
* Obtiene el RUT desde un certificado digital. Busca en la extension
* 2.5.29.17
*
* @param x509
* @return
*/
public static String getRutFromCertificate(X509Certificate x509) {
String rut = null;
Pattern p = Pattern.compile("[\\d]{6,8}-[\\dkK]");
Matcher m = p.matcher(new String(x509.getExtensionValue("2.5.29.17")));
if (m.find())
rut = m.group();
return rut;
}
}